package com.haha;

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

import javax.swing.*;
import java.awt.*;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author shenlinnan
 * @date 2024/8/24 23:46
 */
public class ToggleButtonClient extends JFrame implements NativeKeyListener {

    private static final String WARLOCK_TK = "术士-痛苦";
    private static final String WARLOCK_TK_TEST = "术士-痛苦-测试";
    private static final String WARLOCK_TK_TEST1 = "术士-痛苦-测试1";
    private static final String WARLOCK_EM = "术士-恶魔";
    private static final String WARRIOR_WLK_WQ = "战士-武器-WLK";
    private static final String WARRIOR_WLK_KB = "战士-狂暴-WLK";
    private static final String WARRIOR_WLK_FZ = "战士-防御-WLK";
    private static final String HUNTER = "猎人-生存-WLK";
    private static final String DRUID = "德鲁伊-野德-WLK";
    private static final String PALADIN_NQ = "圣骑士-奶骑";
    private static final String PALADIN_CJQ = "圣骑士-惩戒骑";
    private static final String SM_YS = "萨满-元素";
    private static final String PRIEST_AY = "牧师-暗影";
    private static final String DK_XIE = "死亡骑士-邪-正式服";
    private final boolean isOn = false;
    Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
    private JButton toggleButton;

    private Timer warlockTkTimer;
    private Timer warlockTkTestTimer;
    private Timer warlockTkTest1Timer;
    private Timer warlockEmTimer;
    private Timer warriorTimer;
    private Timer hunterTimer;
    private Timer warriorKbTimer;
    private Timer warriorFzTimer;
    private Timer druidTimer;
    private Timer paladinNqTimer;
    private Timer paladinCjqTimer;
    private Timer smYsTimer;
    private Timer priestAyTimer;
    private Timer dkXieTimer;

    private JComboBox<String> professionComboBox;
    private JLabel professionLabel;
    private List<Integer> centerList = null;


    public ToggleButtonClient() {
        // 提升jnativehook这个组件的日志级别，别一直打印日志
        logger.setLevel(Level.WARNING);
        logger.setUseParentHandlers(false);

        setTitle("游戏助手");
        setSize(500, 350); // 调整窗口大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        initUI();

        try {
            GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());
            System.exit(1);
        }
        GlobalScreen.addNativeKeyListener(this);
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        SwingUtilities.invokeLater(() -> {
            ToggleButtonClient client = new ToggleButtonClient();
            client.setVisible(true);
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("开始执行...");

                    if (client.checkTopRightColor()) {
                        System.out.println("检测到道标可用颜色！");
                        // 执行道标施放逻辑
                    } else {
                        System.out.println("道标条件未满足");
                    }
                }
            });
        });
    }

    private boolean checkTopRightColor() {
        Robot robot;
        try {
            robot = new Robot();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        // 目标颜色 (235, 183, 20)
        Color targetColor = new Color(235, 183, 20);

        // 定义检测范围（x: 2321-2500, y: 100-200）
        int startX = 2321;
        int endX = 2500;
        int startY = 100;
        int endY = 200;

        // 遍历检测区域
        for (int x = startX; x <= endX; x++) {
            for (int y = startY; y <= endY; y++) {
                // 添加容差值 ±3 的模糊匹配
                Color pixelColor = robot.getPixelColor(x, y);
                if (Math.abs(pixelColor.getRed() - 235) < 3 &&
                        Math.abs(pixelColor.getGreen() - 183) < 3 &&
                        Math.abs(pixelColor.getBlue() - 20) < 3) {
                    return true;
                }
            }
        }
        return false;
    }

    private void initUI() {
        // 使用GridBagLayout进行布局
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        // 设置间距
        gbc.insets = new Insets(10, 10, 10, 10);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 职业选择器和确认按钮
        String[] professions = {WARLOCK_TK, WARLOCK_TK_TEST, WARLOCK_TK_TEST1, WARLOCK_EM,
                HUNTER, WARRIOR_WLK_WQ, WARRIOR_WLK_KB, WARRIOR_WLK_FZ,
                DRUID, PALADIN_NQ, PALADIN_CJQ, SM_YS, PRIEST_AY, DK_XIE};
        professionComboBox = new JComboBox<>(professions);
        professionComboBox.setPreferredSize(new Dimension(250, 30));

        // 确认按钮
        JButton confirmButton = new JButton("确认");
        confirmButton.addActionListener(e -> {
            String selectedProfession = (String) professionComboBox.getSelectedItem();
            professionLabel.setText("您当前选择的职业是: " + selectedProfession);
            toggleButton.setText(isOn ? "停止" : "启动");
        });

        // 顶部面板
        JPanel topPanel = new JPanel();
        topPanel.add(professionComboBox);
        topPanel.add(confirmButton);

        // 在initUI()方法的顶部面板部分添加：
        JButton configBtn = new JButton("按键配置");
        configBtn.addActionListener(e -> {
            String selectedProfession = (String) professionComboBox.getSelectedItem();
            if (selectedProfession == null) {
                JOptionPane.showMessageDialog(ToggleButtonClient.this, "请先选择职业！");
                return;
            }
            new KeyConfigDialog(ToggleButtonClient.this, selectedProfession).setVisible(true);
        });
        topPanel.add(configBtn);

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2; // 占据两列
        add(topPanel, gbc);

        // 中部面板
        JPanel middlePanel = new JPanel();
        middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.Y_AXIS));
        professionLabel = new JLabel("您当前选择的职业是:");
        middlePanel.add(professionLabel);

        // 使用说明
        middlePanel.add(new JLabel("使用说明："));
        middlePanel.add(new JLabel("1、必须先选择好职业才能启动，否则无法正常使用"));
        middlePanel.add(new JLabel("2、必须在游戏界面中使用启动快捷键启动。"));

        gbc.gridy = 1;
        gbc.gridwidth = 1; // 恢复为单列
        add(middlePanel, gbc);

        // 底部面板
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); // 垂直排列

        // 启动按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
        toggleButton = new JButton(isOn ? "停止" : "启动");
        toggleButton.addActionListener(e -> {
            try {
                toggleButtonAction();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        });
        buttonPanel.add(new JLabel("快捷键：F12关闭 F11 启动"));
        buttonPanel.add(toggleButton);

        // 版本号面板
        JPanel versionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
        JLabel versionLabel = new JLabel("版本：1.0.2");
        versionPanel.add(versionLabel); // 版本号标签添加到版本面板

        // 将两个面板添加到底部面板
        bottomPanel.add(buttonPanel);
        bottomPanel.add(versionPanel);

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2; // 占据两列
        add(bottomPanel, gbc);

        // 设置面板的边框
        ((JComponent) getContentPane()).setBorder(BorderFactory.createEtchedBorder());
    }


    @Override
    public void nativeKeyPressed(NativeKeyEvent nativeKeyEvent) {
        if (nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_F11) {
            System.out.println("开关打开......" + System.currentTimeMillis());
            try {
                toggleButtonAction();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_F12) {
            System.out.println("开关关闭......");
            if (warlockTkTimer != null) {
                warlockTkTimer.stop();
            }

            toggleButton.setText("启动");
            String selectedProfession = (String) professionComboBox.getSelectedItem();
            if (selectedProfession == null) {
                System.out.println("没有选中职业");
                return;
            }
            switch (selectedProfession) {
                case WARLOCK_TK:
                    if (warlockTkTimer != null) {
                        warlockTkTimer.stop();
                    }
                    break;
                case WARLOCK_TK_TEST:
                    if (warlockTkTestTimer != null) {
                        warlockTkTestTimer.stop();
                    }
                    break;
                case WARLOCK_TK_TEST1:
                    if (warlockTkTest1Timer != null) {
                        warlockTkTest1Timer.stop();
                    }
                    break;
                case WARLOCK_EM:
                    if (warlockEmTimer != null) {
                        warlockEmTimer.stop();
                    }
                    break;
                case WARRIOR_WLK_WQ:
                    if (warriorTimer != null) {
                        warriorTimer.stop();
                    }
                    break;
                case HUNTER:
                    if (hunterTimer != null) {
                        hunterTimer.stop();
                    }
                    break;
                case WARRIOR_WLK_KB:
                    if (warriorKbTimer != null) {
                        warriorKbTimer.stop();
                    }
                    break;
                case WARRIOR_WLK_FZ:
                    if (warriorFzTimer != null) {
                        warriorFzTimer.stop();
                    }
                    break;
                case DRUID:
                    if (druidTimer != null) {
                        druidTimer.stop();
                    }
                    break;
                case PALADIN_NQ:
                    if (paladinNqTimer != null) {
                        paladinNqTimer.stop();
                    }
                    break;
                case PALADIN_CJQ:
                    if (paladinCjqTimer != null) {
                        paladinCjqTimer.stop();
                    }
                    break;
                case SM_YS:
                    if (smYsTimer != null) {
                        smYsTimer.stop();
                    }
                    break;
                case PRIEST_AY:
                    if (priestAyTimer != null) {
                        priestAyTimer.stop();
                    }
                    break;
                case DK_XIE:
                    if (dkXieTimer != null) {
                        dkXieTimer.stop();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {
        // Not needed for this example
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
        // Not needed for this example
    }

    private void toggleButtonAction() throws Exception {
        String selectedProfession = (String) professionComboBox.getSelectedItem();
        if (selectedProfession == null) {
            System.out.println("没有选中职业");
            return;
        }

        if (centerList == null) {
            // 获取魔兽世界的窗口
            WinDef.RECT wowWindow = getWorldOfWarcraftWindow();
            Robot robot;
            try {
                robot = new Robot();
            } catch (AWTException awtException) {
                System.out.println("初始化Robot失败");
                awtException.printStackTrace();
                return;
            }

            // 先定义红色
            Color red = Color.RED;
            Color green = Color.GREEN;

            // 计算方块的宽度
            int winLeft = wowWindow.left;
            int originLeft = wowWindow.left;
            int winTop = wowWindow.top;

            centerList = new LinkedList<>();
            Color splitColor = new Color(128, 128, 128);
            Color originColor = robot.getPixelColor(winLeft, winTop);
            System.out.println("计算色块位置开始" + System.currentTimeMillis());

            int whileCount = 0;
            while (originColor.equals(red) || originColor.equals(green) || originColor.equals(splitColor)) {
                // 检测第一个块
                while (!splitColor.equals(originColor)) {
                    if (whileCount > 200) {
                        System.out.println("循环次数过多，出现错误，强制退出");
                        throw new Exception("色块不对，直接返回");
                    }
                    winLeft++;
                    originColor = robot.getPixelColor(winLeft, winTop);
                    whileCount++;
                }
                // 第一个块的宽度
                int width = winLeft - originLeft;
                int oneMiddle = width / 2;
                int pos = originLeft + oneMiddle;
                boolean contains = centerList.contains(pos);
                if (!contains) {
                    centerList.add(pos);
                }

                // 灰色的时候往右挪一个位置,直到不是灰色为止
                while (originColor.equals(splitColor)) {
                    winLeft++;
                    originColor = robot.getPixelColor(winLeft, winTop);
                }

                originLeft = winLeft;
            }
        }

        System.out.println("检测到色块的位置：" + centerList);
        if (centerList.size() <= 0) {
            throw new Exception("未检测到任何的色块");
        }

        toggleButton.setText("停止");

        System.out.println("计算色块位置结束" + System.currentTimeMillis());
        switch (selectedProfession) {
            case WARLOCK_TK:
                if (warlockTkTimer == null) {
                    warlockTkTimer = new Timer(200, new WarlockTKActionListener(centerList));
                }
                warlockTkTimer.start();
                break;
            case WARLOCK_TK_TEST:
                if (warlockTkTestTimer == null) {
                    warlockTkTestTimer = new Timer(200, new WarlockTKTestActionListener(centerList));
                }
                warlockTkTestTimer.start();
                break;
            case WARLOCK_TK_TEST1:
                if (warlockTkTest1Timer == null) {
                    warlockTkTest1Timer = new Timer(200, new WarlockTKTestActionListener(centerList));
                }
                warlockTkTest1Timer.start();
                break;
            case WARLOCK_EM:
                if (warlockEmTimer == null) {
                    warlockEmTimer = new Timer(200, new WarlockEMActionListener(centerList));
                }
                warlockEmTimer.start();
                break;
            case HUNTER:
                if (hunterTimer == null) {
                    hunterTimer = new Timer(200, new HunterActionListener(centerList));
                }
                hunterTimer.start();
                break;
            case WARRIOR_WLK_WQ:
                if (warriorTimer == null) {
                    warriorTimer = new Timer(200, new WarriorActionListener(centerList));
                }
                warriorTimer.start();
                break;
            case WARRIOR_WLK_KB:
                if (warriorKbTimer == null) {
                    warriorKbTimer = new Timer(200, new WarriorKbActionListener(centerList));
                }
                warriorKbTimer.start();
                break;
            case WARRIOR_WLK_FZ:
                if (warriorFzTimer == null) {
                    warriorFzTimer = new Timer(200, new WarriorFzActionListener(centerList));
                }
                warriorFzTimer.start();
                break;
            case DRUID:
                if (druidTimer == null) {
                    druidTimer = new Timer(200, new DruidActionListener(centerList));
                }
                druidTimer.start();
                break;
            case PALADIN_NQ:
                if (paladinNqTimer == null) {
                    paladinNqTimer = new Timer(200, new PaladinNqActionListener(centerList));
                }
                paladinNqTimer.start();
                break;
            case PALADIN_CJQ:
                if (paladinCjqTimer == null) {
                    paladinCjqTimer = new Timer(200, new PaladinCjqActionListener(centerList));
                }
                paladinCjqTimer.start();
                break;
            case SM_YS:
                if (smYsTimer == null) {
                    smYsTimer = new Timer(200, new SmYsActionListener(centerList));
                }
                smYsTimer.start();
                break;
            case PRIEST_AY:
                if (priestAyTimer == null) {
                    priestAyTimer = new Timer(200, new PriestAyActionListener(centerList));
                }
                priestAyTimer.start();
                break;
            case DK_XIE:
                if (dkXieTimer == null) {
                    dkXieTimer = new Timer(200, new DkXieActionListener(centerList));
                }
                dkXieTimer.start();
                break;
            default:
                break;
        }
    }

    private WinDef.RECT getWorldOfWarcraftWindow() {
        WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, "魔兽世界");
        WinDef.RECT winRect = new WinDef.RECT();
        User32.INSTANCE.GetWindowRect(hwnd, winRect);
        return winRect;
    }

}
